package echecs;

import expression.Ou2;
import expression.Et;
import echecs.Pieces.Piece;
import echecs.Pieces.Piece.Couleur;

import expression.Et2;
import expression.Expression;
import expression.ExpressionBase;
import expression.ExpressionSuite;
import expression.LExpressionSuite;
import expression.LTantQueEtSiNaire;
import expression.SiAlorsSinon;
import expression.SiChaine;
import expression.TantQue3;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static expression.ExpressionBase.*;

public class Algorithme extends ArrayList<Expression> {

    private Etat etat;

    public Algorithme(Couleur pCouleur, Piece[] pPieces) {
        new ExpressionBase();
        etat = new Etat();
        etat.setListeCoups(new ArrayList<Coups>());
        etat.setPieces(pPieces);
        etat.setCouleur(pCouleur);

        Expression[] PiecesParType = {EstTourFouDame, EstPion, EstRoiCavalier};
        Expression[] TSiPionArrVide = {ArrVide, NewCoups};
        Expression SiPionArrVide = new SiAlorsSinon(Arrays.asList(TSiPionArrVide));
        Expression[] PionAuDepartTab = {DistSuivante, SiPionArrVide};
        Expression[] TSiPionAuDepart = {EstPionDep, new ExpressionSuite(PionAuDepartTab)};
        Expression SiPionAuDepart = new SiAlorsSinon(Arrays.asList(TSiPionAuDepart));
        Expression[] PionCaseArriveeVideTab = {NewCoups, SiPionAuDepart};
        Expression[] TPionActionTab = {ArrVide, new ExpressionSuite(PionCaseArriveeVideTab)};
        Expression SiPion = new SiAlorsSinon(Arrays.asList(TPionActionTab));
        Expression[] TArrOccupEtPiecesCoulOpp = {EstCaseArrOccup, PieceCouleurOpp};
        Expression ArrOccupEtPiecesCoulOpp = new Et(Arrays.asList(TArrOccupEtPiecesCoulOpp));
        Expression[] TSiArrOccupEtPiecesCoulOpp = {ArrOccupEtPiecesCoulOpp, NewCoups};
        Expression SiArrOccupEtPiecesCoulOpp = new SiAlorsSinon(Arrays.asList(TSiArrOccupEtPiecesCoulOpp));
        Expression PionAction2 = new TantQue3(EstFinDirPion, SiArrOccupEtPiecesCoulOpp, DirSuivante);
        Expression[] PionActionTab = {InitIndex, SiPion, InitDir, DirSuivante, PionAction2};
        Expression TantQueDirection = new TantQue3(ArrVide, NewCoups, DistSuivante);
        Expression[] FouTourDameActionTab = {TantQueDirection, SiArrOccupEtPiecesCoulOpp, InitDist};
        Expression FouTourDameWhile = new TantQue3(ExisteDirSuiv, new ExpressionSuite(FouTourDameActionTab), DirSuivante);
        Expression ArrOccup_PiecesCoulOpp = new Et2(EstCaseArrOccup, PieceCouleurOpp);
        Expression ArrVideOu_ArrOccupEtPiecesCoulOpp = new Ou2(ArrVide, ArrOccup_PiecesCoulOpp);
        Expression[] TConditionDeplacement = {ArrVideOu_ArrOccupEtPiecesCoulOpp, NewCoups};
        Expression ConditionDeplacement = new SiAlorsSinon(Arrays.asList(TConditionDeplacement));
        Expression DirectionCasRoiCavalier = new TantQue3(ExisteDirSuiv, ConditionDeplacement, DirSuivante);
        Expression[] RoiCavalierActionTab = {InitDist, DirectionCasRoiCavalier};
        Expression[] PieceActionTab = {FouTourDameWhile, new ExpressionSuite(PionActionTab), new ExpressionSuite(RoiCavalierActionTab)};
        Expression TypePiece = new SiChaine(Arrays.asList(PiecesParType), Arrays.asList(PieceActionTab));
        Expression[] ParcourirDirectionsTab = {NewArrayListCoups, InitIndex, TypePiece, AjoutCoupsListe};
        Expression ParcourirDirections = new LExpressionSuite(Arrays.asList(ParcourirDirectionsTab));

        add(ExisteCaseSuiv);
        add(PieceCouleurEtudiee);
        add(ParcourirDirections);
        add(Impression);
        add(CaseSuivante);

        new LTantQueEtSiNaire(this).f(etat);

    }

    List<Coups> listeDesCoups() {
        return etat.getListeCoups();
    }
}